<?php

namespace App\Admin\Controllers;

use App\Admin\Exceptions\SystemModelException;
use App\Admin\Requests\SystemModelRequest;
use App\Admin\Resources\SystemModelResource;
use App\Admin\Filters\SystemModelFilter;
use App\Admin\Models\SystemModel;
use App\Admin\Models\AdminPermission;
use App\Admin\Utils\PermissionChecker;
use App\Admin\Filters\Filter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class SystemModelController extends Controller
{
    public function store(SystemModelRequest $request, SystemModel $systemModel)
    {
        $inputs = $request->validated();
        $inputs['value'] = $inputs['value'] ?? null;
        $systemModel = $systemModel->create($inputs);
        return $this->created(
            SystemModelResource::make($systemModel)
        );
    }

    public function update(SystemModelRequest $request, SystemModel $systemModel)
    {
        $inputs = $request->validated();
        if (isset($inputs['id']) && $inputs['id']) {
            $systemModel = SystemModel::find($inputs['id']);
        } else {
            $id = SystemModel::whereParentId($systemModel->id)
                ->whereSlug('id')
                ->value('id');
            $systemModel = SystemModel::find($id);
        }
        $inputs['value'] = $inputs['value'] ?? null;
        $systemModel->update($inputs);
        $systemModel->updateParam();
        return $this->created(
            SystemModelResource::make($systemModel)
        );
    }
    
    public function edit(Request $request, SystemModel $systemModel)
    {
        if ($systemModel->parent_id===0) {
            $id = SystemModel::whereParentId($systemModel->id)
                ->whereSlug('id')
                ->value('id');
            $systemModel = SystemModel::find($id);
        }
        // 模型字段ID
        $id = $request->input('id');
        if ($id) {
            $systemModel = SystemModel::find($id);
        }
        // 所有字段
        $systemModel->fields = $systemModel->fields($systemModel->parent_id);
        $validation_rules = explode('|', $systemModel->validation_rules);
        foreach ($validation_rules as $key => $value) {
            $value2Arr = explode(":", $value);
            $validation_rules[$value2Arr[0]] = isset($value2Arr[1]) ? explode(",", $value2Arr[1]) : null;
            unset($validation_rules[$key]);
        }
        $formData = $this->formData($systemModel->is_virtual);
        $maxCount = current($formData['validation_rules_map'])['count'];
        foreach ($formData['validation_rules_map'] as $key => $value) {
            // unique 验证规则默认参数
            if ($value['key']=='unique') {
                $value['params'] = [
                    [
                        'key'=>'table_name',
                        'value'=>$systemModel->parent->slug
                    ],
                    [
                        'key'=>'column_name',
                        'value'=>$systemModel->slug
                    ]
                ];
            }
            // exists 验证规则默认参数
            if ($value['key']=='exists') {
                $value['params'] = [
                    [
                        'key'=>'table_name',
                        'value'=>$systemModel->parent->slug
                    ],
                    [
                        'key'=>'column_name',
                        'value'=>$systemModel->slug
                    ]
                ];
            }
            // not_regex/regex 验证规则默认参数
            if ($value['key']=='not_regex' || $value['key']=='regex') {
                $value['params'] = [
                    [
                        'key'=>$value['key'],
                        'value'=>null
                    ]
                ];
            }
            // 已选择的排在最前面，count重新计算
            if (array_key_exists($value['key'], $validation_rules)) {
                $formData['validation_rules_map'][$key]['count'] = $maxCount+$value['count'];
            }
            $pv = $validation_rules[$value['key']] ?? null;
            foreach ($value['params'] as $key3 => $value3) {
                $formData['validation_rules_map'][$key]['param'.$key3.'_key'] = $value3['key'];
                $formData['validation_rules_map'][$key]['param'.$key3.'_value'] = $pv[$key3] ?? null;
            }
            unset($formData['validation_rules_map'][$key]['params']);
        }
        $formData['validation_rules_map'] = array_key_sort($formData['validation_rules_map'], 'count', SORT_DESC);
        $treeSystemModels = app(SystemModel::class)->treeSystemModels($systemModel->parent_id);
        $formData = array_merge($formData, $treeSystemModels);
        return $this->ok(
            SystemModelResource::make($systemModel)
            ->additional($formData)
        );
    }

    public function index(SystemModel $systemModel, Request $request, SystemModelFilter $filter)
    {
        if ($request->__isset('pluck') && $request->input('pluck')) {
            $data = SystemModel::withTrashed()
                ->filter($filter)
                ->pluck($request->input('pluck'))
                ->toArray();
            if ($request->input('pluck') == 'slug') {
                $data = SystemModel::modelSort($data);
            }
            return $this->ok($data);
        } else {
            return $this->ok($systemModel->treeSystemModels());
        }
        
    }

    public function destroy(SystemModel $systemModel)
    {
        $systemModel->forceDelete();
        return $this->noContent();
    }

    public function batchUpdate(Request $request, SystemModel $systemModel)
    {
        $systemModel->saveOrder($request->input('_order', []));

        return $this->created();
    }

    /**
     * 添加和编辑表单所需数据
     *
     * @return array
     */
    protected function formData($isVirtual=false)
    {
        if ($isVirtual) {
            $types_map = SystemModel::$searchTypeMap;
        } else {
            $types_map = SystemModel::$inputTypeMap+SystemModel::$searchTypeMap;
        }
        return [
            'types_map' => SystemModel::typeMapSort($types_map),
            'filter_rules_map' => Filter::$filterRuleMap,
            'validation_rules_map' => SystemModel::validationRuleMapSort(SystemModel::validationRuleMap())
        ];
    }

    public function create()
    {
        return $this->ok($this->formData());
    }

    public function importSystemModels(SystemModelRequest $request, SystemModel $systemModel)
    {
        $file = $request->file('file');
        try {
            $systemModels = $systemModel->replaceFromFile($file);
            return $this->created($systemModels);
        } catch (SystemModelException $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取模型下的字段
     *
     * @param Int $parent_id
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function field(Int $parent_id)
    {
        $systemModel = SystemModel::childrenField($parent_id);
        $data = [
            'list' => $systemModel,
            'parent' => SystemModel::find($parent_id,['name','slug']),
            'filter_rules_map' => Filter::$filterRuleMap,
        ]+SystemModel::groupSceneField($systemModel);
        return $this->ok($data);
    }

    /**
     * 更新模型下的字段
     *
     * @param Int $id
     * @param String $type
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function updateField(Request $request, Int $id)
    {
        $data = $request->input('_order', []);
        foreach ($data as $key => $value) {
            $data[$key]['order'] = $key;
        }
        $systemModel = SystemModel::find($id);
        $systemModel->updateBatch($data);
        return $this->created();
    }

    /**
	* showdoc
	* @catalog 接口简介/全局相关
	* @title 软删除恢复
	* @description 软删除恢复的接口
	* @method PUT
	* @url /admin-api/restore/{router_id}/{id}
    * @param router_id 是 int 路由ID，地址栏参数
    * @param id 是 int 主键，地址栏参数
	* @return {}
	* @return_param 参数名 类型 说明
    * @remark 这里是备注信息
	* @number 99
	*/
    public function restore(Int $route_id, Int $id){
        $model = $this->getModelByVid($route_id);
        if (!AdminPermission::checkAdminPermission($model['slug'],'PUT')){
            PermissionChecker::error();
        }
        DB::update("UPDATE {$model['slug']} SET deleted_at=NULL WHERE id = {$id}");
        if (isset($model['slug']) && $model['slug']=='config_categories') {
            // 恢复所选配置
            DB::update("UPDATE configs SET deleted_at=NULL WHERE category_id = {$id}");
        } 
        return $this->created();
    }

    /**
	* showdoc
	* @catalog 接口简介/全局相关
	* @title 彻底删除
	* @description 彻底删除的接口
	* @method DELETE
	* @url /admin-api/forceDelete/{router_id}/{id}
    * @param router_id 是 int 路由ID，地址栏参数
    * @param id 是 int 主键，地址栏参数
	* @return {}
	* @return_param 参数名 类型 说明
    * @remark 这里是备注信息
	* @number 99
	*/
    public function forceDelete(Int $route_id, Int $id){
        $model = $this->getModelByVid($route_id);
        if (!AdminPermission::checkAdminPermission($model['slug'],'DELETE')){
            PermissionChecker::error();
        }
        DB::delete("DELETE FROM {$model['slug']} WHERE id = {$id}");
        if (isset($model['slug']) && $model['slug']=='config_categories') {
            // 彻底删除所选配置
            DB::delete("DELETE FROM configs WHERE category_id = {$id}");
        } 
        return $this->noContent();
    }

    /**
	* showdoc
	* @catalog 接口简介/全局相关
	* @title 批量软删除
	* @description 批量软删除的接口
	* @method DELETE
	* @url /admin-api/deleteBatch/{router_id}
    * @param router_id 是 int 路由ID，地址栏参数
    * @param id 是 int 主键，多个用英文逗号隔开
	* @return {}
	* @return_param 参数名 类型 说明
    * @remark 这里是备注信息
	* @number 99
	*/
    public function deleteBatch(Int $route_id){
        $model = $this->getModelByVid($route_id);
        if (!AdminPermission::checkAdminPermission($model['slug'],'DELETE')){
            PermissionChecker::error();
        }
        $ids = request()->input('id');
        if ($ids){
            // 删除时间
            $deleted_at = date('Y-m-d H:i:s');
            $ids = implode(',', $ids);
            if (isset($model['slug']) && $model['slug']=='system_models') {
                DB::delete("DELETE FROM {$model['slug']} WHERE id IN ({$ids})");
            } else {
                DB::update("UPDATE {$model['slug']} SET deleted_at='{$deleted_at}' WHERE id IN ({$ids})");
                if (isset($model['slug']) && $model['slug']=='config_categories') {
                    // 批量软删除所选配置
                    DB::update("UPDATE configs SET deleted_at='{$deleted_at}' WHERE category_id IN ({$ids})");
                } 
            }
        }
        return $this->created();
    }

    /**
    * showdoc
    * @catalog 接口简介/全局相关
    * @title 批量彻底删除
    * @description 批量彻底删除的接口
    * @method DELETE
    * @url /admin-api/forceDeleteBatch/{router_id}
    * @param router_id 是 int 路由ID，地址栏参数
    * @param id 是 int 主键，多个用英文逗号隔开
    * @return {}
    * @return_param 参数名 类型 说明
    * @remark 这里是备注信息
    * @number 99
    */
    public function forceDeleteBatch(Int $route_id){
        $model = $this->getModelByVid($route_id);
        if (!AdminPermission::checkAdminPermission($model['slug'],'DELETE')){
            PermissionChecker::error();
        }
        $ids = request()->input('id');
        if ($ids == 'all'){
            // 清空所有
            DB::delete("DELETE FROM {$model['slug']} WHERE 1");
            if (isset($model['slug']) && $model['slug']=='config_categories') {
                // 清空所有配置
                DB::delete("DELETE FROM configs WHERE 1");
            }
        } elseif (is_array($ids)) {
            $ids = implode(',', $ids);
            DB::delete("DELETE FROM {$model['slug']} WHERE id IN ({$ids})");
            if (isset($model['slug']) && $model['slug']=='config_categories') {
                // 清空所选配置
                DB::delete("DELETE FROM configs WHERE category_id IN ({$ids})");
            }
        } 
        return $this->noContent();
    }

    /**
	* showdoc
	* @catalog 接口简介/全局相关
	* @title 软删除批量恢复
	* @description 软删除批量恢复的接口
	* @method DELETE
	* @url /admin-api/restoreBatch/{router_id}
    * @param router_id 是 int 路由ID，地址栏参数
    * @param id 是 int 主键，多个用英文逗号隔开
	* @return {}
	* @return_param 参数名 类型 说明
    * @remark 这里是备注信息
	* @number 99
	*/
    public function restoreBatch(Int $route_id){
        $model = $this->getModelByVid($route_id);
        if (!AdminPermission::checkAdminPermission($model['slug'],'PUT')){
            PermissionChecker::error();
        }
        $ids = request()->input('id');
        if ($ids) {
            $ids = implode(',', $ids);
            DB::update("UPDATE {$model['slug']} SET deleted_at=NULL WHERE id IN ({$ids})");
            if (isset($model['slug']) && $model['slug']=='config_categories') {
                // 恢复所选配置
                DB::update("UPDATE configs SET deleted_at=NULL WHERE category_id IN ({$ids})");
            }
        }
        return $this->created();
    }
}
